import { trim } from 'lodash';

export interface ASTAttribute {
  key: string;
  value: string;
}

export interface ASTNode {
  tagName?: string;
  attributes?: ASTAttribute[];
  content?: string;
  children?: ASTNode[];
}

export type AST = ASTNode[];

/**
 * 将HTML字符串解析为AST
 */
export const toAST = (html: string): AST => {
  const ast: AST = [];
  let currentIndex = 0;
  const tagRegex = /<(\/?)([a-zA-Z][a-zA-Z0-9]*)([^>]*)>/g;
  let match;

  const parseAttributes = (attrString: string): ASTAttribute[] => {
    const attributes: ASTAttribute[] = [];
    const attrRegex = /([a-zA-Z-]+)(?:="([^"]*)")?/g;
    let attrMatch;

    while ((attrMatch = attrRegex.exec(attrString)) !== null) {
      const [, key, value] = attrMatch;
      if (key && key !== '/') {
        attributes.push({ key, value: value || '' });
      }
    }

    return attributes;
  };

  const parseContent = (): string => {
    const startIndex = currentIndex;
    let content = '';
    let depth = 0;

    while (currentIndex < html.length) {
      const char = html[currentIndex];

      if (char === '<') {
        const nextChar = html[currentIndex + 1];
        if (nextChar === '/') {
          if (depth === 0) break;
          depth--;
        } else if (nextChar && /[a-zA-Z]/.test(nextChar)) {
          depth++;
        }
      }

      content += char;
      currentIndex++;
    }

    return content.replace(/<[^>]*>/g, '').trim();
  };

  const parseNode = (): ASTNode | null => {
    if (currentIndex >= html.length) return null;

    const char = html[currentIndex];
    if (char === '<') {
      // 解析标签
      tagRegex.lastIndex = currentIndex;
      match = tagRegex.exec(html);

      if (!match) return null;

      const [, isClosing, tagName, attributes] = match;
      currentIndex = tagRegex.lastIndex;

      if (isClosing) {
        return null; // 结束标签，返回 null
      }

      const node: ASTNode = {
        tagName,
        attributes: parseAttributes(attributes),
      };

      // 自闭合标签
      if (attributes.includes('/>') || ['img', 'br', 'hr'].includes(tagName)) {
        return node;
      }

      // 解析子节点
      const children: ASTNode[] = [];
      let child;
      while ((child = parseNode()) !== null) {
        children.push(child);
      }

      if (children.length > 0) {
        node.children = children;
      }

      return node;
    }

    // 解析文本内容
    const content = parseContent();
    if (content) {
      return { content };
    }

    return null;
  };

  while (currentIndex < html.length) {
    const node = parseNode();
    if (node) {
      ast.push(node);
    }
  }

  return ast;
};

/**
 * 从HTML字符串中提取纯文本（用于备注处理）
 */
export const extractTextFromHTML = (html: string): string => {
  if (!html) return '';

  // 简单的HTML标签移除
  const text = html
    .replace(/<[^>]*>/g, '') // 移除所有HTML标签
    .replace(/&nbsp;/g, ' ') // 替换HTML实体
    .replace(/&amp;/g, '&')
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>')
    .replace(/&quot;/g, '"')
    .replace(/&#39;/g, "'")
    .trim();

  return text;
};

/**
 * 解析HTML备注为纯文本数组（模拟原始代码的DOMParser功能）
 */
export const parseRemarkHTML = (html: string): string[] => {
  if (!html) return [];

  // 使用正则表达式模拟DOMParser的功能
  const pTags = html.match(/<p[^>]*>(.*?)<\/p>/gs);

  if (pTags) {
    return pTags
      .map((pTag) => {
        // 提取p标签内的文本内容
        const content = pTag.replace(/<p[^>]*>/, '').replace(/<\/p>/, '');
        return extractTextFromHTML(content);
      })
      .filter((text) => text.length > 0);
  }

  // 如果没有p标签，直接提取所有文本
  return [extractTextFromHTML(html)];
};
